/*
** $Id: linit.c $
** 初始化库的函数，用于lua.c和其他客户端
** 请参见lua.h中的版权声明
*/

/* 定义文件内使用的宏 */
#define linit_c
#define LUA_LIB

/*
** 如果你将Lua嵌入到你的程序中，并且需要打开标准库，
** 可以在你的程序中调用luaL_openlibs函数。如果你需要不同的库集，
** 可以复制这个文件到你的项目中，并根据需要进行编辑。
**
** 你还可以预加载库，以便后续的'require'能够打开已经链接到应用程序的库。
** 要这样做，请执行以下代码：
**
**  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
**  lua_pushcfunction(L, luaopen_modname);
**  lua_setfield(L, -2, modname);
**  lua_pop(L, 1);  // 移除PRELOAD表
*/

#include "lprefix.h"

/* 包含标准C库的头文件 */
#include <stddef.h>

/* 包含Lua公共头文件 */
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"


/*
** 这些库由lua.c加载，并且对任何Lua程序都可用
*/
static const luaL_Reg loadedlibs[] = {
  {LUA_GNAME, luaopen_base},        /* Lua基础库 */
  {LUA_LOADLIBNAME, luaopen_package}, /* Lua包加载库 */
  {LUA_LOADLIBNAME_C, luaopen_package}, 
  {LUA_COLIBNAME, luaopen_coroutine}, /* Lua协程库 */
  {LUA_COLIBNAME_C, luaopen_coroutine}, 
  {LUA_TABLIBNAME, luaopen_table},    /* Lua表库 */
  {LUA_TABLIBNAME_C, luaopen_table},    
  {LUA_IOLIBNAME, luaopen_io},        /* Lua I/O库 */
  {LUA_IOLIBNAME_C, luaopen_io},      
  {LUA_OSLIBNAME, luaopen_os},        /* Lua操作系统库 */
  {LUA_OSLIBNAME_C, luaopen_os},      
  {LUA_STRLIBNAME, luaopen_string},   /* Lua字符串库 */
  {LUA_STRLIBNAME_C, luaopen_string}, 
  {LUA_MATHLIBNAME, luaopen_math},    /* Lua数学库 */
  {LUA_MATHLIBNAME_C, luaopen_math},  
  {LUA_UTF8LIBNAME, luaopen_utf8},    /* Lua UTF-8库 */
  {LUA_DBLIBNAME, luaopen_debug},     /* Lua调试库 */
  {LUA_DBLIBNAME_C, luaopen_debug},   
  {NULL, NULL}                         /* 结束标志 */
};


/*
** 打开Lua标准库
**
** @param L Lua状态机指针。
** @description 根据'loadedlibs'数组中的定义，调用“require”函数打开相应的库，并将结果设置到全局表中。
** @see luaL_requiref
*/
LUALIB_API void luaL_openlibs (lua_State *L) {
  const luaL_Reg *lib;
  /* 遍历'loadedlibs'数组，依次“require”各个库并将其结果设置到全局表中 */
  for (lib = loadedlibs; lib->func; lib++) {
    luaL_requiref(L, lib->name, lib->func, 1);
    lua_pop(L, 1);  /* 移除库函数的引用 */
  }
}

